﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace FrogEngine
{
	public class ThirdPersonCamera : BaseCamera
	{
		public ThirdPersonCamera(IEngine engine, IOriented3DGameEntity entityToFollow, float mass)
			: base(engine, entityToFollow.Position, entityToFollow.World)
		{
			this.entityToFollow = entityToFollow;
			this.Mass = mass;
			this.NearPlane = 1;
			this.FarPlane = 100000;
			this.LookAtOffset = new Vector3(0, 2.8f, 0);
			this.Stiffness = 1800f;
			this.Damping = 500f;
			this.Mass = 50f;
		}

		private IOriented3DGameEntity entityToFollow;

		/// <summary>
		/// Desired position of the camera relative to the entity the
		/// camera is following.
		/// </summary>
		public Vector3 EntitySpacePosition { get; set; }

		/// <summary>
		/// The desired position of the camera in world space.
		/// </summary>
		public Vector3 DesiredPosition { get; set; }

		public Vector3 LookAtOffset { get; set; }
		public Vector3 LookAt { get; set; }
		public float Stiffness { get; set; }
		public float Damping { get; set; }

		public override void Update(GameTime gameTime)
		{
			Matrix transform = Matrix.Identity;
			transform.Forward = entityToFollow.Forward;
			transform.Up = entityToFollow.Up;
			transform.Right = Vector3.Cross(entityToFollow.Forward, entityToFollow.Up);

			DesiredPosition = entityToFollow.Position + Vector3.TransformNormal(EntitySpacePosition, transform);
			LookAt = entityToFollow.Position + Vector3.TransformNormal(LookAtOffset, transform);

			Vector3 stretch = Position - DesiredPosition;
			Force = -Stiffness * stretch - Damping * Velocity;

			base.Update(gameTime);
		}

		public void Reset()
		{
			Matrix transform = Matrix.Identity;
			transform.Forward = entityToFollow.Forward;
			transform.Up = entityToFollow.Up;
			transform.Right = Vector3.Cross(entityToFollow.Forward, entityToFollow.Up);

			DesiredPosition = entityToFollow.Position + Vector3.TransformNormal(EntitySpacePosition, transform);
			LookAt = entityToFollow.Position + Vector3.TransformNormal(LookAtOffset, transform);
			this.Velocity = Vector3.Zero;
			this.Position = this.DesiredPosition;
		}
	}
}
